#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include "mk_pthread.h"

//#include "anyka_types.h"
#define DEBUG_LOG

#if !defined(DEBUG_LOG)
#define MK_TID_LOG(...) // printf
#else
#define MK_TID_LOG 			printf
#endif



int mk_pthread_default(pthread_t *ptid,pthread_entry entry,void *arg)
{

	int result = pthread_create(ptid, NULL,entry, arg);

	if (result != 0) {
		MK_TID_LOG("Create  thread failed(%s).\n",strerror(result));
		return -1;
	}

	return 0;
}

int mk_pthread_realtime_default(pthread_t *ptid,pthread_entry entry,void *arg)
{
	int ret =0;
	pthread_attr_t attr;
	struct sched_param priparam;
	
	pthread_attr_init(&attr);
	 /*
    PTHREAD_EXPLICIT_SCHED: 不继承，只有不继承父线程的调度策略才可以设置线程的调度策略PTHREAD_INHERIT_SCHED: 继承父进程的调度策略
    */
	ret =  pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED); 
	if (ret!=0){
		printf("pthread_attr_setinheritsched err %s\n",strerror(ret));
	}
	#if USE_DEFAULT_STACK
	pthread_attr_setstacksize(&attr, DEFAULT_THREAD_STACK);
	#endif
	// pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
	pthread_attr_setschedpolicy(&attr, SCHED_RR);
     
	priparam.sched_priority = 1;//sched_get_priority_max(SCHED_RR);//  99;
	pthread_attr_setschedparam(&attr, &priparam);

	int result = pthread_create(ptid, &attr,entry, arg);
	pthread_attr_destroy(&attr);

	if (result != 0) {
		MK_TID_LOG("Create  thread failed(%s).\n",strerror(result));
		return -1;
	}

	return 0;
}

int mk_pthread(pthread_t *ptid,pthread_entry entry,void *arg)
{
	int ret=0;
	pthread_attr_t attr;
	struct sched_param priparam;
	
	pthread_attr_init(&attr);
	ret = pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED); 
	if (ret!=0){
		printf("pthread_attr_setinheritsched err %s\n",strerror(ret));
	}
	#if USE_DEFAULT_STACK
	pthread_attr_setstacksize(&attr, DEFAULT_THREAD_STACK);
	#endif
	// pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
   
	pthread_attr_setschedpolicy(&attr, SCHED_RR);
   
	priparam.sched_priority = sched_get_priority_max(SCHED_RR);//  99;
	pthread_attr_setschedparam(&attr, &priparam);

	int result = pthread_create(ptid, &attr,entry, arg);
	pthread_attr_destroy(&attr);

	if (result != 0) {
		MK_TID_LOG("Create  thread failed(%s).\n",strerror(result));
		return -1;
	}

	return 0;
}
 
int mk_pthread_priority(pthread_t *ptid,pthread_entry entry,void *arg,int priority)
{
	int ret =0;
	pthread_attr_t attr;
	struct sched_param priparam;
	
	pthread_attr_init(&attr);
	ret = pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED); 
	if (ret!=0){
		printf("pthread_attr_setinheritsched err %s\n",strerror(ret));
	}
	#if USE_DEFAULT_STACK
	pthread_attr_setstacksize(&attr, DEFAULT_THREAD_STACK);
	#endif
	// pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
	pthread_attr_setschedpolicy(&attr, SCHED_RR);
	priparam.sched_priority = priority;//  99;
	pthread_attr_setschedparam(&attr, &priparam);

	int result = pthread_create(ptid, &attr,entry, arg);
	pthread_attr_destroy(&attr);

	if (result != 0) {
		MK_TID_LOG("Create  thread failed(%s).\n",strerror(result));
		return -1;
	}

	return 0;
}

int mk_pthread_priority_stack(pthread_t *ptid,pthread_entry entry,void *arg,size_t stack_size, int priority)
{
	int ret =0;

	pthread_attr_t attr;
	struct sched_param priparam;
	
	pthread_attr_init(&attr);
	ret = pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED); 
	if (ret!=0){
		printf("pthread_attr_setinheritsched err %s\n",strerror(ret));
	}
	if(stack_size > 0)
		pthread_attr_setstacksize(&attr, stack_size);
	#if USE_DEFAULT_STACK
	else
		pthread_attr_setstacksize(&attr, DEFAULT_THREAD_STACK);
	#endif
	
	// pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
	pthread_attr_setschedpolicy(&attr, SCHED_RR);
	priparam.sched_priority = priority;//  99;
	pthread_attr_setschedparam(&attr, &priparam);

	int result = pthread_create(ptid, &attr,entry, arg);
	pthread_attr_destroy(&attr);

	if (result != 0) {
		MK_TID_LOG("Create  thread failed(%s).\n",strerror(result));
		return -1;
	}

	return 0;
}


int mk_pthread_priority_stack_detached(pthread_t *ptid,pthread_entry entry,void *arg,
			size_t stack_size, int priority,bool isdetached)
{
	int ret =0;
	pthread_attr_t attr;
		
	pthread_attr_init(&attr);
	ret = pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED); 
	if (ret!=0){
		printf("pthread_attr_setinheritsched err %s\n",strerror(ret));
	}
	if(stack_size > 0)
		pthread_attr_setstacksize(&attr, stack_size);
	#if USE_DEFAULT_STACK
	else
		pthread_attr_setstacksize(&attr, DEFAULT_THREAD_STACK);
	#endif
	
	if(isdetached)
	 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
	
	pthread_attr_setschedpolicy(&attr, SCHED_RR);
	
	if(priority > 0){
		struct sched_param priparam;
		priparam.sched_priority = priority;//  99;
		pthread_attr_setschedparam(&attr, &priparam);
	}

	int result = pthread_create(ptid, &attr,entry, arg);
	pthread_attr_destroy(&attr);

	if (result != 0) {
		MK_TID_LOG("Create  thread failed(%s).\n",strerror(result));
		return -1;
	}

	return 0;
}



int mk_pthread_cancel(pthread_t *ptid)
{
	int ret;
	
	ret = pthread_cancel(*ptid);
	if(ret != 0){
		MK_TID_LOG("pthread cancel err\n");
		return -1;
	}

	ret = pthread_join(*ptid,NULL);
	if(ret != 0){
		MK_TID_LOG("pthread join err\n");
		return -1;
	}

	return 0;
}
